package com.android.calculator;

import android.content.Context;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.Editable;
import android.text.InputType;
import android.text.Spanned;
import android.text.method.NumberKeyListener;
import android.util.AttributeSet;
import android.view.animation.TranslateAnimation;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.ViewSwitcher;

/**
 * Provides vertical scrolling for the input/result EditText.
 */
public class CalculatorDisplay extends ViewSwitcher {
	// only these chars are accepted from keyboard
	private static final char[] ACCEPTED_CHARS = "0123456789.+-*/\u2212\u00d7\u00f7()!%^".toCharArray();

	private static final int ANIM_DURATION = 500;

	enum Scroll {
		UP, DOWN, NONE
	}

	TranslateAnimation inAnimUp;
	TranslateAnimation outAnimUp;
	TranslateAnimation inAnimDown;
	TranslateAnimation outAnimDown;

	private Logic mLogic;
	private boolean mComputedLineLength = false;

	public CalculatorDisplay(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	// @Override
	// protected void onFinishInflate() {
	// super.onFinishInflate();
	// CalculatorActivity calc = (CalculatorActivity) getContext();
	// calc.adjustFontSize((TextView)getChildAt(0));
	// calc.adjustFontSize((TextView)getChildAt(1));
	// }

	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		if (!mComputedLineLength) {
			mLogic.setLineLength(getNumberFittingDigits((TextView) getCurrentView()));
			mComputedLineLength = true;
		}
	}

	// compute the maximum number of digits that fit in the
	// calculator display without scrolling.
	private int getNumberFittingDigits(TextView display) {
		int available = display.getWidth() - display.getTotalPaddingLeft() - display.getTotalPaddingRight();
		Paint paint = display.getPaint();
		float digitWidth = paint.measureText("2") / 10f;
		return (int) (available / digitWidth);
	}

	@SuppressWarnings("deprecation")
	protected void setLogic(Logic logic) {
		mLogic = logic;
		NumberKeyListener calculatorKeyListener = new NumberKeyListener() {
			public int getInputType() {
				// Don't display soft keyboard.
				return InputType.TYPE_NULL;
			}

			protected char[] getAcceptedChars() {
				return ACCEPTED_CHARS;
			}

			public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
				/*
				 * the EditText should still accept letters (eg. 'sin') coming
				 * from the on-screen touch buttons, so don't filter anything.
				 */
				return null;
			}

		};

		Editable.Factory factory = new CalculatorEditable.Factory(logic);
		for (int i = 0; i < 2; ++i) {
			EditText text = (EditText) getChildAt(i);
			text.setBackgroundDrawable(null);
			text.setEditableFactory(factory);
			text.setKeyListener(calculatorKeyListener);
		}
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldW, int oldH) {
		inAnimUp = new TranslateAnimation(0, 0, h, 0);
		inAnimUp.setDuration(ANIM_DURATION);
		outAnimUp = new TranslateAnimation(0, 0, 0, -h);
		outAnimUp.setDuration(ANIM_DURATION);

		inAnimDown = new TranslateAnimation(0, 0, -h, 0);
		inAnimDown.setDuration(ANIM_DURATION);
		outAnimDown = new TranslateAnimation(0, 0, 0, h);
		outAnimDown.setDuration(ANIM_DURATION);
	}

	void insert(String delta) {
		EditText editor = (EditText) getCurrentView();
		int cursor = editor.getSelectionStart();
		editor.getText().insert(cursor, delta);
	}

	EditText getEditText() {
		return (EditText) getCurrentView();
	}

	Editable getText() {
		EditText text = (EditText) getCurrentView();
		return text.getText();
	}

	void setText(CharSequence text, Scroll dir) {
		if (getText().length() == 0) {
			dir = Scroll.NONE;
		}

		if (dir == Scroll.UP) {
			setInAnimation(inAnimUp);
			setOutAnimation(outAnimUp);
		} else if (dir == Scroll.DOWN) {
			setInAnimation(inAnimDown);
			setOutAnimation(outAnimDown);
		} else { // Scroll.NONE
			setInAnimation(null);
			setOutAnimation(null);
		}

		EditText editText = (EditText) getNextView();
		editText.setText(text);
		// Calculator.log("selection to " + text.length() + "; " + text);
		editText.setSelection(text.length());
		showNext();
	}

	void setSelection(int i) {
		EditText text = (EditText) getCurrentView();
		text.setSelection(i);
	}

	int getSelectionStart() {
		EditText text = (EditText) getCurrentView();
		return text.getSelectionStart();
	}

	@Override
	protected void onFocusChanged(boolean gain, int direction, Rect prev) {
		// Calculator.log("focus " + gain + "; " + direction + "; " + prev);
		if (!gain) {
			requestFocus();
		}
	}

	void subEqualText() {
		EditText editText = (EditText) getCurrentView();
		String text = editText.getText().toString();
		if (text.startsWith("=")) {
			text = text.substring(1);
			editText.setText(text);
			editText.setSelection(text.length());
		}
	}

	boolean isStartWithEqual() {
		EditText editText = (EditText) getCurrentView();
		String text = editText.getText().toString();
        return text.startsWith("=");
	}
}
